﻿using AgencyManagerSystem.Common;
using Dapper.Contrib.Extensions;
using Dapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Collections;

namespace AgencyManagerSystem.DataFetcher
{
    public abstract class BaseFetcher<T> where T:DBModel
    {
        protected long COUNTER;
        protected string tableName;
        protected FullUserProfile userProfile;
        public BaseFetcher()
        {
            TableAttribute tableNameAttribute = typeof(T).GetCustomAttribute<TableAttribute>();
            if(tableNameAttribute!=null)
            {
                tableName = tableNameAttribute.Name;
            }
            if (MyHttpContext.Current.Items.ContainsKey(Definer.CURRENT_PROFILE))
                userProfile = MyHttpContext.Current.Items[Definer.CURRENT_PROFILE] as FullUserProfile;
        }
        public virtual void AddDefaultFilter(StringBuilder stringBuilder,DynamicParameters dynamicParameters)
        {

        }
        public virtual IList<T> List(IEnumerable<Condition> conditions , int pos, int size , out int count)
        {
            count = 0;
            IList<T> result = null;
            StringBuilder conditionString = new StringBuilder();
            DynamicParameters dynamicParameters = new DynamicParameters();
            if (conditions != null)
            {
                foreach (Condition condition in conditions)
                {
                    StringBuilder orCondition = new StringBuilder(" 1=0 ");
                    foreach (string key in condition.Key.Split(new char[] { '|'}, StringSplitOptions.RemoveEmptyEntries))
                    {
                        string keyStr = String.Format("@{0}_{1}", key, COUNTER++);
                        orCondition.AppendFormat(" OR {0} {1} {2} ", key, condition.Op, keyStr);
                        dynamicParameters.Add(keyStr, condition.Value);
                    }
                    conditionString.AppendFormat(" AND ({0})",orCondition);
                }
            }
            AddDefaultFilter(conditionString,dynamicParameters);
            string sqlstr = String.Format("SELECT * FROM {0} WHERE 1=1 {1} ORDER BY AUTOID DESC LIMIT {2},{3}", tableName, conditionString, pos, size);
            LogHelper.Debug(this.GetType().Name, sqlstr);
            string sqlstrCount = String.Format("SELECT COUNT(*) FROM {0} WHERE 1=1 {1}  ", tableName, conditionString);
            try
            {
                result = DBHelper.GetTran().Query<T>(sqlstr, dynamicParameters).AsList();
                count = DBHelper.GetTran().Query<Int32>(sqlstrCount, dynamicParameters).AsList().First();
            }
            catch (Exception ex)
            {
                LogHelper.Err(this.GetType().Name, ex.Message + "-" + ex.StackTrace);
            }
            return result;
        }
        public virtual IList<T> List(Condition[] conditions = null, int pos = 0, int size = 1000)
        {
            IList<T> result = null;
            StringBuilder conditionString = new StringBuilder();
            DynamicParameters dynamicParameters = new DynamicParameters();
            if (conditions != null)
            {
                foreach (Condition condition in conditions)
                {
                    StringBuilder orCondition = new StringBuilder(" 1=0 ");
                    foreach (string key in condition.Key.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        string keyStr = String.Format("@{0}_{1}", key, COUNTER++);
                        orCondition.AppendFormat(" OR {0} {1} {2} ", key, condition.Op, keyStr);
                        dynamicParameters.Add(keyStr, condition.Value);
                    }
                    conditionString.AppendFormat(" AND ({0})", orCondition);
                }
            }
            AddDefaultFilter(conditionString, dynamicParameters);

            string sqlstr = String.Format("SELECT * FROM {0} WHERE 1=1 {1} ORDER BY AUTOID DESC LIMIT {2},{3}", tableName, conditionString, pos, size);
            LogHelper.Debug(this.GetType().Name, sqlstr);
            try
            {
                result = DBHelper.GetTran().Query<T>(sqlstr, dynamicParameters).AsList();
            }
            catch(Exception ex)
            {
                LogHelper.Err(this.GetType().Name, ex.Message + "-" + ex.StackTrace);
            }
            return result;
        }

        public virtual IList<T> List(params string[] keyValStr)
        {
            return List(Condition.MakeCondition(keyValStr));
        }
        public virtual T Get(int autoid)
        {
            try
            {
                IList<T> ls = List(String.Format("AutoId={0}", autoid));
                if (ls.Count > 0)
                    return ls.First();
                return null;
            }
            catch(Exception ex)
            {
                LogHelper.Err(this.GetType().Name, ex.Message + "-" + ex.StackTrace);
            }
            return null;
        }
    }
}
